package org.iks.common.aop.serializer;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import org.iks.common.aop.ParameterMapping;
import org.iks.common.aop.SplitStringParameter;
import org.iks.common.constant.Constant;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Author kzou
 * Date 2023/12/23 10:02
 * Description: 将字符串转为集合 可以与 {@link SplitStringParameter 配合使用}
 */
public class StringToListDeserializer extends JsonDeserializer<List<String>> implements ContextualDeserializer {

    /**
     * 默认分隔符
     */
    private String separator = Constant.Comma;

    SplitStringParameter splitStringParameter;

    @Override
    public List<String> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        String values = jsonParser.getText();
        if (values == null || values.isEmpty()) {
            return Collections.emptyList();
        }
        // 分割
        String[] items = values.split(separator);
        List<String> result = new ArrayList<>(items.length);
        result.addAll(Arrays.asList(items));
        if (splitStringParameter == null) {
            return result;
        }
        // 去重
        if (splitStringParameter.isDistinct()) {
            result = result.stream().distinct().collect(Collectors.toList());
        }
        // 别名映射
        ParameterMapping[] mappings = splitStringParameter.mappings();
        if (mappings.length != 0) {
            Map<String, ParameterMappingRecord> mappingRecordMap = Arrays.stream(mappings)
                    .map(it -> new ParameterMappingRecord(it, it.mappingName()))
                    .collect(Collectors.toMap(it -> it.parameterName, it -> it));
            result = result.stream().map(it -> {
                ParameterMappingRecord mappingRecord = mappingRecordMap.get(it);
                return mappingRecord == null ? it : mappingRecord.parameterMapping.mappingName();
            }).collect(Collectors.toList());
        }
        // 驼峰与下划线转换
        if (splitStringParameter.enableCamelCaseToUnderline()) {
            result = result.stream().map(StrUtil::toUnderlineCase).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) throws JsonMappingException {
        splitStringParameter = beanProperty.getAnnotation(SplitStringParameter.class);
        if (splitStringParameter != null) {
            this.separator = splitStringParameter.separator();
        }
        return this;
    }

    static class ParameterMappingRecord {
        private ParameterMapping parameterMapping;
        private String parameterName;

        public ParameterMappingRecord(ParameterMapping it, String mappingName) {
        }
        public ParameterMapping getParameterMapping() {
            return parameterMapping;
        }

        public String getParameterName() {
            return parameterName;
        }
    }


}
